#include<iostream>
#include<emmintrin.h>
#include<ctime>
#include<math.h>
#define INT_COUNT (5*1024*1024)

inline int calculate(int input){
	int val = (input % 99)*(input/98);
	val = val ?val:1;
	double n = sqrt(sqrt((double)(unsigned)input *1.3));
	double m = sqrt(sqrt((double)(unsigned)val*0.9));	
	return (int)((double)input*(double)val*m/(n?n:1.1));

}

int run_prefetch(const int *array, int size,int step){
	int result = 0;
	for(int i =0;i<step;i++){
		for(int j = i;j<size;j+=step){
			int k = j+step;
			if(k<size){
//				__builtin_prefetch(&array[k],0,1);
				_mm_prefetch((char*)&array[k],_MM_HINT_T0);
//				_mm_clflush(&array[k]);			
			}
			result += calculate(array[j]);
		}
	}
	return result;
}

int run_naive(const int *array, int size,int step){
	int result = 0;
	for(int i =0;i<step;i++){
		for(int j = i;j<size;j+=step){
			result += calculate(array[j]);
		}
	}
	return result;
}

using namespace std;
int main(){
	clock_t start,end;
	int* array = new int[INT_COUNT];
	int res1,res2;
	for( int i = 0;i< INT_COUNT;i++){
		array[i]=i;
	}

	start = clock();
	res1 = run_naive(array,INT_COUNT,1024);
	end = clock();
	cout<< "naive:   "<< res1<<endl<<end-start<<endl;

	start = clock();
	res2 = run_prefetch(array,INT_COUNT,1024);
	end = clock();
	cout<< "prefetch:"<< res2<<endl<<end-start<<endl;



	return 0 ;
}
